home *** CD-ROM | disk | FTP | other *** search
/ MacFormat España 15 / macformat_15.iso / Shareware Internet / Desarrolladores / gray image 2.1 / morph_filter.cc < prev    next >
Text File  |  1995-10-08  |  5KB  |  150 lines

  1. // This may look like C code, but it is really -*- C++ -*-
  2. /*
  3.  ************************************************************************
  4.  *
  5.  *               Grayscale Image
  6.  *
  7.  *           Morphological filtration of the image
  8.  *    
  9.  *    The program implements the Function-Set-Processing (FSP)
  10.  *    for the gray-scale images and boolean patterns. Refer to the
  11.  *    Sec. II D of the paper.
  12.  *
  13.  * Note, the program expects the binary pattern to lie entirely into the
  14.  * I quadrant, i.e. abscissae and ordinates of every pattern point are
  15.  * both non-negative. It makes possible to implement erosion and dilation,
  16.  * two fundamental morphological operations, inplace.
  17.  * 
  18.  * $Id$
  19.  *
  20.  ************************************************************************
  21.  */
  22.  
  23. #ifdef __GNUC__
  24. #pragma implementation
  25. #endif
  26. #include "morph_filter.h"
  27. #include "std.h"
  28. #include <minmax.h>
  29.  
  30.  
  31. /*
  32.  *------------------------------------------------------------------------
  33.  *            Binary Pattern service operations
  34.  *        
  35.  */
  36.  
  37.                 // Allocate and clear arrays to hold
  38.                 // the specific no. of points
  39. void BinaryPattern::allocate(const int _npoints)
  40. {
  41.   npoints = _npoints;
  42.   assure(npoints >0, "Cannot allocate pattern with non-positive cardinality");
  43.   assure((xs = (int *)calloc(npoints,sizeof(int))) != 0,"Out of memory");
  44.   assure((ys = (int *)calloc(npoints,sizeof(int))) != 0,"Out of memory");
  45. }
  46.                     // Create a pattern of a predefined
  47.                     // shape
  48. BinaryPattern::BinaryPattern(const PatternNames name,const int size)
  49. {
  50.   assure(size > 0,"Pattern size has got to be positive");
  51.  
  52.   if( name == Square )
  53.   {
  54.     allocate(sqr(size));
  55.     register int i,j;
  56.     register int *xp = &xs[0];
  57.     register int *yp = &ys[0];
  58.  
  59.     for(i=0; i<size; i++)
  60.       for(j=0; j<size; j++)
  61.     *xp++ = i, *yp++ = j;
  62.  
  63.     assert( xp-&xs[0] == npoints && yp-&ys[0] == npoints );
  64.   }
  65.   else
  66.     _error("Sorry, standard pattern %d hasn't implemented yet",name);
  67. }
  68.  
  69.                 // Destructor
  70. BinaryPattern::~BinaryPattern(void)
  71. {
  72.   assert( npoints > 0 && xs != 0 && ys != 0 );
  73.   free(xs);
  74.   free(ys);
  75. }
  76.  
  77. /*
  78.  *------------------------------------------------------------------------
  79.  *            Dilation of the image inplace
  80.  * dest(k,l) = MAX{ src(k-i,l-j) } i=pattern.x(n), j=pattern.y(n)
  81.  * n=0..pattern.card
  82.  * Out-of-image pixels for src are assumed to be zeros.
  83.  * If pattern.x(n) >= 0 and pattern.y(n) >= 0, the operation can be
  84.  * performed inplace. Indeed, dilation of the point (k,l) of the image
  85.  * requires the (k,l)-th point itself and some pixels to the left and
  86.  * to the top of the current point. So, the image has to be scanned
  87.  * from the right to the left and from the bottom to the top, and
  88.  * the current point of the image can be substituted with its dilated
  89.  * value
  90.  */
  91.  
  92. void dilation(IMAGE& image, const BinaryPattern& pattern)
  93. {
  94.   image.is_valid();
  95.   register int k,l;
  96.  
  97.   for(k=image.q_nrows()-1; k>=0; k--)        // From bottom to the top
  98.     for(l=image.q_ncols()-1; l>=0; l--)        // and from right to left
  99.     {
  100.       GRAY& pixel = image(k,l);
  101.       register GRAY max_val = pixel;
  102.       register int n,i,j;
  103.       for(n=0; n<pattern.card(); n++)
  104.     if( (i=k-pattern.y(n)) >= 0 && (j=l-pattern.x(n)) >= 0 )
  105.       max_val = max(max_val,image(i,j));
  106.         else
  107.       max_val = max(max_val,0);
  108.       
  109.       pixel = max_val;
  110.     }
  111. }
  112.  
  113. /*
  114.  *------------------------------------------------------------------------
  115.  *            Erosion of the image inplace
  116.  * dest(k,l) = MIN{ src(k+i,l+j) } i=pattern.x(n), j=pattern.y(n)
  117.  * n=0..pattern.card
  118.  * Out-of-image pixels for src are assumed to be zeros
  119.  * If pattern.x(n) >= 0 and pattern.y(n) >= 0, the operation can be
  120.  * performed inplace. Indeed, erosion of the point (k,l) of the image
  121.  * requires the (k,l)-th point itself and some pixels to the right and
  122.  * to the bottom of the current point. So, the image has to be scanned
  123.  * from left to right and from the top to the bottom, and
  124.  * the current point of the image can be substituted with its erosed
  125.  * value
  126.  */
  127.  
  128. void erosion(IMAGE& image, const BinaryPattern& pattern)
  129. {
  130.   image.is_valid();
  131.   register int k,l;
  132.  
  133.   for(k=0; k<image.q_nrows(); k++)        // From bottom to the top
  134.     for(l=0; l<image.q_ncols(); l++)        // and from right to left
  135.     {
  136.       GRAY& pixel = image(k,l);
  137.       register GRAY min_val = pixel;
  138.       register int n,i,j;
  139.       for(n=0; n<pattern.card(); n++)
  140.     if( (i=k+pattern.y(n)) < image.q_nrows()  && 
  141.         (j=l+pattern.x(n)) < image.q_ncols() )
  142.       min_val = min(min_val,image(i,j));
  143.         else
  144.       min_val = min(min_val,0);
  145.       
  146.       pixel = min_val;
  147.     }
  148. }
  149.  
  150.